﻿// -----------------------------------------------------------------------
// <copyright file="Floor.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Cubezicles
{
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    /// <summary>
    /// Draw the ground plane carpet.  Use tiles to repeat textures.
    /// </summary>
    public class Floor : DrawableGameComponent
    {
        const string TextureName = "Textures/carpet";

        Texture2D texture;
        Quad quad;
        BasicEffect quadEffect;

        // Size, in world coordinates, of each carpet instance
        const float TileSize = 5.0f;

        // We will create a grid of dimensions [-tileRows, tileRows] x [-tileRows, tileRows]
        const int tileRows = 16, tileCols = 14;

        public Floor(Game game) : base(game) { this.DrawOrder = (int)Game1.DisplayOrder.Background; }

        protected override void LoadContent()
        {
            var cam = Game.Services.GetService<ICamera>();

            // Load texture image
            texture = Game.Content.Load<Texture2D>(TextureName);

            // Set up ground quad
            quad = new Quad(Vector3.Zero, Vector3.UnitY, Vector3.UnitZ, TileSize, TileSize);

            // Set up ground effects
            quadEffect = new BasicEffect(GraphicsDevice);
            quadEffect.Projection = cam.ProjectionMatrix;
            quadEffect.TextureEnabled = true;
            quadEffect.Texture = texture;

            base.LoadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            var viewMat = Game.Services.GetService<ICamera>().ViewMatrix;
            int N = (tileRows + 1) / 2;
            int M = (tileCols + 1) / 2;

            quadEffect.View = viewMat;
            // A row of (tileRows) tiles
            for (int i = -N; i <= N; ++i)
            {
                // A column of (tileRows) tiles
                for (int j = -M; j <= M; ++j)
                {
                    // Model matrix for rendering
                    quadEffect.World = Matrix.CreateTranslation(new Vector3(TileSize * i, 0, TileSize * j));

                    // Draw this tile
                    foreach (var pass in quadEffect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(
                            PrimitiveType.TriangleList,
                            quad.Vertices, 0, 4,
                            quad.Indexes, 0, 2);
                    }
                }
            }

            base.Draw(gameTime);
        }
    }
}
